﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace Cofe.Core.Utils
{
    /// <summary>
    /// The default parser store filter into a 
    /// string something like the following:    
    /// xyz:abc OR def:"abc de" 
    /// </summary>
    public class FilterStringSerializer : IPropertySerializer
    {
         #region Constructor

        public FilterStringSerializer()
        {

        }

        #endregion

        #region Methods


        private static bool readNextToken(string filterStr,
            int startat, out int nextTokenPos, out string key, out string value)
        {

            if (startat < filterStr.Length)
            {
                var match = regexNextToken.Match(filterStr, startat);
                if (match != null && !String.IsNullOrEmpty(match.Value))
                {
                    key = match.Groups["key"].Value;
                    value = match.Groups["value"].Value.Trim(new char[] { '\"' });
                    nextTokenPos = match.Index + match.Length + 1;
                    if (String.IsNullOrEmpty(key))
                    {
                        key = value;
                        value = "";
                    }
                    return true;
                }
            }

            key = value = null;
            nextTokenPos = startat;
            return false;
        }


        public string PropertyToString(IEnumerable<Tuple<string, string>> properties)
        {
            return string.Join(" ",
               (from p in properties
                select String.Format(
                String.IsNullOrEmpty(p.Item2) ? "{0}" : 
                p.Item2.Contains(" ") ? "{0}:\"{1}\"" : "{0}:{1}",
                p.Item1, p.Item2)).ToArray());   
        }

        public IEnumerable<Tuple<string, string>> StringToProperty(string propertyString)
        {
            string key, value;
            int currentPos = 0, nextPos;

            while (readNextToken(propertyString, currentPos, out nextPos, out key, out value))
            {
                yield return new Tuple<string, string>(key, value);
                currentPos = nextPos;
            }
        }

        #endregion

        #region Data

        private static Regex regexNextToken = new Regex(
            RegexPatterns.ParseParamStringNextTokenPattern);

        #endregion

        #region Public Properties

        #endregion

    }
}
